; *****************************************************************
; Fist stage bootloader for El Torito ISO9660 - no emulation mode
; Reindeer OS - boot loader
;
; Copyrights 2011 Michal Saman, m.saman@designplus.cz.
; This source code is release under the Apache License 2.0.
; http://www.apache.org/licenses/LICENSE-2.0
; *****************************************************************

%define PRG_CODE_SEGMENT			0x07C0

org		0					; we set registers later
bits	16					; we start in 16 bit Real Mode

start:		jmp  main

times	8-($-$$) db 0		; offset 8 for boot-information table
; boot information table is made by mkisofs -boot-info-table
bi_pri_vol_descriptor	resd	1			; Primary volume descripotro - LBA address
bi_boot_file_lba		resd	1			; LBA of boot file
bi_boot_file_size		resd	1			; Length of boot file is bytes
bi_checksum				resd	1			; 32bit checksum
bi_reserved				resb	40			; reserved

; read buffer for READ_SECTOR_EXT function
%define READ_BUFF_SEG				0x0900
%define	READ_BUFF_OFF				0x0000

; stack segment, offset
%define STACK_INIT_SEG				0x07C0
%define STACK_INIT_OFF				0xFFFF

; includes
%include "boot/stdio16.inc.asm"
%include "boot/iso9660.inc.asm"
%include "boot/read_file_ext.inc.asm"

; data used by program
imageName_iso	db		"RDKRLD.SYS;1", 0  				; 12 characters
msgWelcome		db		"Reindeer OS boot loader (ISO9660 mode)", 0x0D, 0x0A, 0x00
msgLoading		db		"Loading", 0
msgCrLf     	db		0x0D, 0x0A, 0x00
numberBuffer	db 		"12345678901234567890", 0
boot_drive		db		0


;***********************************
; Bootloader entry point
;***********************************

main:
	cli									; disable interrupts requests, we don't need them yet
	mov		ax, PRG_CODE_SEGMENT		; setup register to point our code segment
	mov		ds, ax						; set all segments pointing to our code segment
	mov		es, ax
	mov		fs, ax
	mov		gs, ax

	mov 	[boot_drive], dl			; save bios boot drive number to memory

	mov		ax, STACK_INIT_SEG			; setup our stack to very first segment
	mov		ss, ax
	mov		sp, STACK_INIT_OFF			; set start of stack
	sti
	
	mov		si, msgWelcome				; welcome message, we are here :)
	call	Puts16
	mov		si, msgLoading				; let's show that we have some work
	call	Puts16

	mov		ax, WORD [bi_pri_vol_descriptor]	; setup PVD address from boot info structure to memory loc. where function loadFileIso expext it.
	mov		[iso_pri_vol_descriptor], ax

	call	loadFileIso					; call function to find and load file from ISO9660
	cmp		ax, 0						; check result code (0 = OK)
	jne		.problemStop				; if not OK, end program

.loadedOk:
	mov		bx, 1								; save mode to BX register (0 - fat12, 1 - iso9660)
	mov		cx, [bi_pri_vol_descriptor]			; save PVD position
	push	WORD READ_BUFF_SEG					; point return call stack to our address of file in memory (read buffer)
	push	WORD READ_BUFF_OFF
	retf										; goto memory - start RDKLDR.SYS

.problemStop:
	xor		ax, ax						; clear ax
	mov		ah, 0x00					; set function id
	int		0x16						; wait for keypress
	int		0x19						; warm boot computer

times 2048 - ($-$$) db 0				; we have to be 2048 bytes, set rest of bytes with 0...
